package org.simple.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import org.simple.cache.ICourseTypeCache;
import org.simple.client.PageConfigClient;
import org.simple.client.RedisClient;
import org.simple.domain.CourseType;
import org.simple.mapper.CourseTypeMapper;
import org.simple.service.ICourseTypeService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author zj
 * @since 2020-02-19
 */
@Service
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {
   @Autowired
   private CourseTypeMapper courseTypeMapper;

   @Autowired
   private ICourseTypeCache courseTypeCache;
   @Autowired
   private PageConfigClient pageConfigClient;
    @Autowired
    private RedisClient redisClient;

    @Override
    public List<CourseType> treeData(long pid) {
        /*  缓存中有就去缓存中拿,没有时查询数据库再放入缓存中*/
       List<CourseType> courseTypes= courseTypeCache.getTreeData();
        if(courseTypes!=null &&courseTypes.size()>0){
            System.out.println("我是缓存中的数据...");
            return  courseTypes;
        }else {
           List<CourseType> courseTypesOfDb= treeDataLoop(pid);
            System.out.println("我不是缓存中的数据");
           courseTypeCache.setTreeData(courseTypesOfDb);
                return courseTypesOfDb;
        }

    }
/*
 * 页面静态化
  * */
    @Override
    public void staticIndexPageInit() {
//1页面名称写死，约定大于配置
        String pageName = "CourseSiteIndex";

        //2 需要一个保存到redis数据库的key
        String dataKey="CourseSiteIndex_data";
        //本来就是从redis获取，还要在放一次，其他页面静态化的场景不一定有缓冲
        List<CourseType> courseTypes = this.treeData(0L);
        //课程处理
        Map<String,Object> courseTypesData = new HashMap<>();
        courseTypesData.put("courseTypes",courseTypes);
        //职位
        redisClient.add(dataKey, JSONArray.toJSONString(courseTypesData)); //{courseTypes:[]}

        //3 调用方法模板+数据=静态页面
        pageConfigClient.staticPage(pageName,dataKey);


    }
    /*  循环方案二：无限极数据*/

    private List<CourseType> treeDataLoop(long pid) {
        /*  查询所有节点*/
        List<CourseType> allNodes = courseTypeMapper.selectList(null);
        Map<Long,CourseType> allNodeDto=new HashMap<>();

        for (CourseType courseType : allNodes) {
            allNodeDto.put(courseType.getId(), courseType);
        }
        /*  组织关系 */
        List<CourseType> result=new ArrayList<>();
        /*  若为一级节点，则放入result中,如果不是一级节点，则需要建立父子关系：即将自己作为父亲的儿子添加进去*/
        for (CourseType courseType:allNodes){

            if(courseType.getPid().intValue()==0){
                 result.add(courseType);
                }else{
                    Long  pidTmp=courseType.getPid();
                     CourseType parent = allNodeDto.get(pidTmp);
                     parent.getChildren().add(courseType);
            }
        }
        return result;
    }

    /*  递归：自己调自己
*       返回条件
*   */
    private List<CourseType> treeDataRecursion(long pid) {
        List<CourseType> children = courseTypeMapper.selectList(new EntityWrapper<CourseType>().eq("pid", pid));
        if (children==null || children.size()<1)
        {
            return null;
        }
        for (CourseType child : children) {
            //自己调用自己
            List<CourseType> cTmp =treeDataRecursion(child.getId());
            child.setChildren(cTmp);
        }
        return children;
    }


    //重写增删改方法-同步缓存


    @Override
    public boolean insert(CourseType entity) {

        courseTypeMapper.insert(entity);
        courseTypeCache.setTreeData(treeDataLoop(0));
        return true;
    }

    @Override
    public boolean deleteById(Serializable id) {
        courseTypeMapper.deleteById(id);
        courseTypeCache.setTreeData(treeDataLoop(0));
        return true;
    }

    @Override
    public boolean updateById(CourseType entity) {
        courseTypeMapper.updateById(entity);
        courseTypeCache.setTreeData(treeDataLoop(0));
        return true;
    }
}
